package com.safeluck.floatwindow;

import android.bluetooth.BluetoothProfile;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.util.Size;
import android.view.SurfaceHolder;

import com.google.gson.Gson;
import com.orhanobut.logger.Logger;
import com.safeluck.floatwindow.bean.MediaInfo;
import com.safeluck.floatwindow.util.CamparaUtil;
import com.safeluck.floatwindow.util.FileUtil;
import com.safeluck.floatwindow.util.MyLog;
import com.safeluck.floatwindow.util.TimeUtil;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * aaa
 * Created by lzw on 2018/9/27. 14:45:27
 * 邮箱：632393724@qq.com
 * All Rights Saved! Chongqing AnYun Tech co. LTD
 */
public class MediaRecordCls{
    private  int FRS = 20;
    private static  int RECORD_TIME_SEC = 2;//
    private static final String TAG = "MediaRecordCls";
    private String FILE_NAME;// 视频信息，视频文件、名
    private MediaRecorder mediaRecorder ;
    private Camera mCamera;
    private  MediaArgu mediaArgu;
    private int errcode = 4;//正常 结束 ，5==就是片段结束
    private ServiceFinishListener serviceFinishListener;
    private boolean isCameraBad = false; //内部相机出现异常打不开
    private int width = 320;//分辨率宽
    private int height = 240;//分辨率高
    private String outSDPath;
    private MediaInfo mediaInfo;
    private List<MediaArgu.ScreenSolution> screenSolutions = new ArrayList<>();
    {
        screenSolutions.add(new MediaArgu.ScreenSolution(320,240));
        screenSolutions.add(new MediaArgu.ScreenSolution(640,480));
        screenSolutions.add(new MediaArgu.ScreenSolution(1280,720));
    }

    private void init(SurfaceHolder surfaceHolder,String pathS) {

        mediaRecorder = new MediaRecorder();

        if (mCamera != null){
            mCamera.release();
        }
        try {
            mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
        } catch (RuntimeException e) {
            isCameraBad = true;
            MyLog.d(TAG,"内部相机异常RunTimeException openFail");
            e.printStackTrace();
        }
//        mCamera.setDisplayOrientation(270);
        mCamera.unlock();
        mediaRecorder.setCamera(mCamera);
//        addPreviewSize();

        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);


//        mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P));
        if (mediaArgu != null){
            RECORD_TIME_SEC = mediaArgu.getRecordTime();
            if (RECORD_TIME_SEC == 0){
                RECORD_TIME_SEC = 10;
            }
            MyLog.i(TAG,"录像传进来的时间"+RECORD_TIME_SEC);
        }
        //+100主要是为了RECORD_TIME_SEC setmaxduration 和 STOPRTMP时间一致。两次stop的话，mediaRecord.stop 会failed 返回-1007
        mediaRecorder.setMaxDuration(RECORD_TIME_SEC*1000+1000);
        mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
            @Override
            public void onInfo(MediaRecorder mediaRecorder, int arg1, int extra) {
                switch (arg1){
                    case MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:
                        errcode = 5;
                        MyLog.i("setOnInfoListener MEDIA_RECORDER_INFO_MAX_DURATION_REACHED"+errcode);
                        if (serviceFinishListener != null){
                            serviceFinishListener.stopSelf();
                        }
//                        if(mediaRecorder != null){
//                            Log.d(TAG,"停止本地录制，移除监听释放资源");
//                            try {
//                                if (mediaInfo != null){
//                                    long curTime = System.currentTimeMillis();
//
//                                    long cur = curTime - TimeUtil.video_formatTime(mediaInfo.start_time);
//                                    cur = cur/1000L;
//
//                                    mediaInfo.play_time = (int)cur;
//                                    if (serviceFinishListener != null){
//                                        MyLog.i(TAG, "stop: 返回本机录像时长="+(int)cur);
//                                        if (isCameraBad){
//                                            //相机打开异常结束
//                                            serviceFinishListener.badCamera(-2);
//                                        }else{
//                                            //停止录像 通知录像时长文件名
//                                            serviceFinishListener.devVideoDur((int)cur);
//                                        }
//                                    }
//                                }
////                writeInfoaboutVideo();
//                                mediaRecorder.stop();
//                                mediaRecorder.reset();
//                                mediaRecorder.release();
//                            } catch (IllegalStateException e) {
//                                e.printStackTrace();
//                            } catch (RuntimeException e) {
//                                e.printStackTrace();
//                            } catch (Exception e) {
//                                e.printStackTrace();
//                            }
//
//                        }

                        break;
                }
            }
        });
        if (mediaArgu != null){
            MediaArgu.ScreenSolution screenSolution = mediaArgu.getM_screen();
            MyLog.d(TAG,"传进来的分辨率，width="+screenSolution.width+"传进来的分辨率，height="+screenSolution.height);
            FRS = mediaArgu.getFrameRate();
            if (screenSolution != null){
                boolean isUsedOut = false;
                for (int i = 0; i < screenSolutions.size(); i++) {
                    if(screenSolutions.get(i).equals(screenSolution)){
                        MyLog.i( "支持传进来的分辨率: width:"+screenSolution.width+" height:"+screenSolution.height);
                        isUsedOut = true;
                        width = screenSolution.width;
                        height = screenSolution.height;
                        mediaRecorder.setVideoSize(screenSolution.width,screenSolution.height);
                        break;
                    }
                }
                if (!isUsedOut){
                    MyLog.i(TAG, "不支持传进来的分辨率（使用320): RunTimeException");
                    mediaRecorder.setVideoSize(width,height);
                }



            }else{
                MyLog.i("init: 沒有傳分辨率");
                mediaRecorder.setVideoSize(width,height);
            }

            int videoEncodingBitRate = mediaArgu.getCodeRate();
            Log.i(TAG, "init: videoEncodingBitRate="+videoEncodingBitRate);
            if (videoEncodingBitRate != 0){
                mediaRecorder.setVideoEncodingBitRate(videoEncodingBitRate*1024);
//                mediaInfo = writeMediaInfo(videoEncodingBitRate/1024,FRS,width,height);
            }else{
                float bitRate = 1024*1024*0.6f;
                videoEncodingBitRate = (int)(bitRate/1024);
//                mediaInfo = writeMediaInfo(videoEncodingBitRate,FRS,width,height);
                Log.i(TAG, "init: (int)bitRate="+(int)bitRate);
                //码率
                mediaRecorder.setVideoEncodingBitRate((int)bitRate);
            }

        }

        mediaRecorder.setAudioEncodingBitRate(30000);
        mediaRecorder.setAudioChannels(2);
        mediaRecorder.setAudioSamplingRate(48000);
        MyLog.i("帧率="+FRS);
        mediaRecorder.setVideoFrameRate(FRS);
        mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
        mediaRecorder.setOrientationHint(270);
        Log.i(TAG, "init: pathS="+pathS);
        this.outSDPath = pathS;
        long curTime = System.currentTimeMillis();
        FILE_NAME = TimeUtil.video_formatTime(curTime);
        mediaRecorder.setOutputFile(pathS+ File.separator+ FILE_NAME+".mp4");
        MyLog.i("init: vidoe file="+FILE_NAME+".mp4");



    }

    private void addPreviewSize() {
        Camera.Parameters parameters = mCamera.getParameters();
        List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
        for (Camera.Size size:sizes){
            MyLog.i(TAG,String.format("screenSolutions add widht=%d,height=%d",size.width,size.height));
        screenSolutions.add(new MediaArgu.ScreenSolution(size.width,size.height));
        }
    }


    public void starter(SurfaceHolder surfaceHolder,MediaArgu mediaArgu, String path, ServiceFinishListener serviceFinishListener) {
        this.mediaArgu = mediaArgu;

        this.serviceFinishListener = serviceFinishListener;

        if (mediaRecorder == null){
            init(surfaceHolder,path);
        }



        if (mediaRecorder != null){

            try {
                //准备录制
                mediaRecorder.prepare();
                //开始录制
                Log.i(TAG, "starter:开始录制 ");
                mediaInfo = writeMediaInfo();
                mediaInfo.start_time = TimeUtil.video_formatTime(System.currentTimeMillis());
                mediaRecorder.start();
                if (serviceFinishListener != null){
                    serviceFinishListener.start();
                    Logger.d("init: 返回给客户端dev的分辨率");
                    serviceFinishListener.devCameraRes(new Size(width,height));

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void relaseMedia(){
        if (mediaRecorder != null){
            mediaRecorder.release();
            mediaRecorder = null;
        }
        if (mCamera != null){
            mCamera.release();
        }
    }

    public String getFILE_NAME() {
        return outSDPath+ File.separator+ FILE_NAME+".mp4";
    }

    public void stop() {
        if(mediaRecorder != null){
            Log.d(TAG,"停止本地录制，移除监听释放资源");
            try {
                if (mediaInfo != null){
                    long curTime = System.currentTimeMillis();

                    long cur = curTime - TimeUtil.video_formatTime(mediaInfo.start_time);
                    cur = cur/1000L;

                    mediaInfo.play_time = (int)cur;
                    if (serviceFinishListener != null){
                        MyLog.i(TAG, "stop: 返回本机录像时长="+(int)cur);
                        if (isCameraBad){
                            //相机打开异常结束
                            serviceFinishListener.badCamera(-2);
                        }else{
                            //停止录像 通知录像时长文件名
                        serviceFinishListener.devVideoDur((int)cur,errcode);
                        }
                    }
                }
//                writeInfoaboutVideo();
                mediaRecorder.stop();
                mediaRecorder.setOnInfoListener(null);
                mediaRecorder.setPreviewDisplay(null);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (RuntimeException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            //释放资源
            mediaRecorder.release();
            //引用置为空
            mediaRecorder = null;
        }

        relaseMedia();
    }
    private MediaInfo writeMediaInfo(/*int codeRate,int frameRate,int width,int height*/){
        MediaInfo mediaInfoTemp =null;




            if (mediaInfoTemp == null){
                mediaInfoTemp = new MediaInfo();
            }

//            mediaInfoTemp.codeRate = codeRate;
//            mediaInfoTemp.frameRate = frameRate;
//            mediaInfoTemp.width = width;
//            mediaInfoTemp.height = height;
            return mediaInfoTemp;


    }
    private void writeInfoaboutVideo() {
        FileUtil.writeToDisk(outSDPath,FILE_NAME+".txt",new Gson().toJson(mediaInfo));
    }

    interface ServiceFinishListener{
        void stopSelf();
        void start();
        void devCameraRes(Size size);
        void devVideoDur(int timeS,int errcode);

        void badCamera(int i);
    }
}
